#include <SecuenciaManager.h>
#include <fstream>
#include <string>
#include <BetMakerDevelopFramework.h> // para el memory utils
#include <QtCore/QDateTime> // para la fecha

using namespace std;

int SecuenciaManager::getSecuencia()
{
	int secReturn = 0;
	unsigned short anio = 0;
	unsigned char mes = 0;
	unsigned char dia = 0;
	try
	{
		// levanto el archivo
		fstream secFile;
		secFile.open(".\\secuencia" , ios::binary | ios::in | ios::out );

		if ( secFile.is_open() )
		{
			// leo la actual secuencia y la fecha de la ultima actualizacion
			char bufferIn[ SIZE_SECUENCIA + SIZE_ANIO + (SIZE_DIA_MES * 2) ];
			secFile.seekg( 0 );
			secFile.read( bufferIn , SIZE_SECUENCIA + SIZE_ANIO + (SIZE_DIA_MES * 2) );

			// obtengo la secuencia
			BMMemoryUtils mu;
			mu.MemoryCopy( &secReturn , bufferIn , SIZE_SECUENCIA );

			// obtengo la fecha
			mu.MemoryCopy( &anio , bufferIn + SIZE_SECUENCIA , SIZE_ANIO );

			mu.MemoryCopy( &mes , bufferIn + SIZE_SECUENCIA + SIZE_ANIO , SIZE_DIA_MES );

			mu.MemoryCopy( &dia , bufferIn + SIZE_SECUENCIA + SIZE_ANIO + SIZE_DIA_MES , SIZE_DIA_MES );
			
			// verifico si se trata de una secuenci del mismo dia o si se debeb resetear a cero la secuencia por ser un dia nuevo
			QDate date(QDate::currentDate());
			if ( date.year() != anio ||  date.month() != mes || date.day() !=  dia )
			{
				// Si la fecha ha cambiado actualizo la secuencia y la grabo junto a la nueva fecha
				secReturn = 0;
				unsigned short anioOut = date.year();
				unsigned char mesOut = date.month();
				unsigned char diaOut = date.day();

				mu.MemoryCopy( bufferIn , &secReturn , SIZE_SECUENCIA);
				mu.MemoryCopy( bufferIn + SIZE_SECUENCIA , &anioOut , SIZE_ANIO);
				mu.MemoryCopy( bufferIn + SIZE_SECUENCIA + SIZE_ANIO, &mesOut , SIZE_DIA_MES);
				mu.MemoryCopy( bufferIn + SIZE_SECUENCIA + SIZE_ANIO + SIZE_DIA_MES , &diaOut , SIZE_DIA_MES);

				secFile.seekp( 0 );
				secFile.write( bufferIn , SIZE_SECUENCIA + SIZE_ANIO + (SIZE_DIA_MES * 2));
			}

			// cierro el archivo y retorno el valor
			secFile.close();
			
			return secReturn;
		}
		else
		{
			if ( saveSecuencia( 0 ) )
			{
				return 0;
			}
			else
			{
				// TODO: HAY QUE LOGEAR EL ERROR DE APERTURA DEL ARCHIVO DE SECUENCIA
				// Y ENVIAR UNA ALARMA, POR EJEMPLO POR MAIL.
				secReturn = -1;
				return secReturn;
			}
		}
	}
	catch (...)
	{
		// TODO: RELANZAR EXCEPTION O BIEN LOGEAR ERROR Y ENVIAR ALARMA POR MAIL 
		secReturn = -1;
		return secReturn;
	}
}
		
		

int SecuenciaManager::incSecuencia()
{
	int secReturn = 0;
	unsigned short anio = 0;
	unsigned char mes = 0;
	unsigned char dia = 0;
	try
	{
		// levanto el archivo
		fstream secFile;
		secFile.open(".\\secuencia" , ios::binary | ios::in | ios::out );

		if ( secFile.is_open() )
		{
			// leo la actual secuencia y la fecha de la ultima actualizacion
			char bufferIn[ SIZE_SECUENCIA + SIZE_ANIO + (SIZE_DIA_MES * 2) ];
			secFile.seekg( 0 );
			secFile.read( bufferIn , SIZE_SECUENCIA + SIZE_ANIO + (SIZE_DIA_MES * 2) );

			// obtengo la secuencia
			BMMemoryUtils mu;
			mu.MemoryCopy( &secReturn , bufferIn , SIZE_SECUENCIA );

			// obtengo la fecha
			mu.MemoryCopy( &anio , bufferIn + SIZE_SECUENCIA , SIZE_ANIO );

			mu.MemoryCopy( &mes , bufferIn + SIZE_SECUENCIA + SIZE_ANIO , SIZE_DIA_MES );

			mu.MemoryCopy( &dia , bufferIn + SIZE_SECUENCIA + SIZE_ANIO + SIZE_DIA_MES , SIZE_DIA_MES );
			
			// verifico si se trata de una secuenci del mismo dia o si se debeb resetear a cero la secuencia por ser un dia nuevo
			QDate date(QDate::currentDate());
			if ( date.year() != anio ||  date.month() != mes || date.day() !=  dia )
			{
				// Si la fecha ha cambiado actualizo la secuencia y la grabo junto a la nueva fecha
				secReturn = 1;
				unsigned short anioOut = date.year();
				unsigned char mesOut = date.month();
				unsigned char diaOut = date.day();

				mu.MemoryCopy( bufferIn , &secReturn , SIZE_SECUENCIA);
				mu.MemoryCopy( bufferIn + SIZE_SECUENCIA , &anioOut , SIZE_ANIO);
				mu.MemoryCopy( bufferIn + SIZE_SECUENCIA + SIZE_ANIO, &mesOut , SIZE_DIA_MES);
				mu.MemoryCopy( bufferIn + SIZE_SECUENCIA + SIZE_ANIO + SIZE_DIA_MES , &diaOut , SIZE_DIA_MES);

				secFile.seekp(0);
				secFile.write( bufferIn , SIZE_SECUENCIA + SIZE_ANIO + (SIZE_DIA_MES * 2));
			}
			else
			{
				// si la fecha es la misma incremento y guardo secuecia 
				secReturn++;
				mu.MemoryCopy( bufferIn , &secReturn , SIZE_SECUENCIA);
				secFile.seekp(0);
				secFile.write( bufferIn , SIZE_SECUENCIA );
			}

			// cierro el archivo y retorno el valor
			secFile.close();
			return secReturn;
		}
		else
		{
			if ( saveSecuencia( 1 ) )
			{
				return 1;
			}
			else
			{
				// TODO: HAY QUE LOGEAR EL ERROR DE APERTURA DEL ARCHIVO DE SECUENCIA
				// Y ENVIAR UNA ALARMA, POR EJEMPLO POR MAIL.
				secReturn = -1;
				return secReturn;
			}
		}
	}
	catch (...)
	{
		// TODO: RELANZAR EXCEPTION O BIEN LOGEAR ERROR Y ENVIAR ALARMA POR MAIL 
		secReturn = -1;
		return secReturn;
	}
}


bool SecuenciaManager::saveSecuencia( int secuencia )
{
	try
	{
		// levanto el archivo
		ofstream secFile;
		secFile.open(".\\secuencia" , ios::binary );

		if ( secFile.is_open() )
		{
			char bufferOut[SIZE_SECUENCIA + SIZE_ANIO + (SIZE_DIA_MES*2)];

			// Actualizo el archivo
			QDate date(QDate::currentDate());
		
			unsigned short anioOut = date.year();
			unsigned char mesOut = date.month();
			unsigned char diaOut = date.day();

			BMMemoryUtils mu;

			mu.MemoryCopy( bufferOut , &secuencia , SIZE_SECUENCIA);
			mu.MemoryCopy( bufferOut + SIZE_SECUENCIA , &anioOut , SIZE_ANIO);
			mu.MemoryCopy( bufferOut + SIZE_SECUENCIA + SIZE_ANIO, &mesOut , SIZE_DIA_MES);
			mu.MemoryCopy( bufferOut + SIZE_SECUENCIA + SIZE_ANIO + SIZE_DIA_MES , &diaOut , SIZE_DIA_MES);

			secFile.write( bufferOut , SIZE_SECUENCIA + SIZE_ANIO + (SIZE_DIA_MES * 2));

			// cierro el archivo y retorno el valor
			secFile.close();
			
			return true;
		}
		else
		{
			// TODO: HAY QUE LOGEAR EL ERROR DE APERTURA DEL ARCHIVO DE SECUENCIA
			// Y ENVIAR UNA ALARMA, POR EJEMPLO POR MAIL.
			return false;
		}
	}
	catch (...)
	{
		// TODO: RELANZAR EXCEPTION O BIEN LOGEAR ERROR Y ENVIAR ALARMA POR MAIL 
		return false;
	}
}